package com.invengo.module_check.data.repsitory.business.source.impl;


import android.annotation.SuppressLint;
import android.os.Build;
import android.text.TextUtils;

import androidx.annotation.RequiresApi;

import com.blankj.utilcode.util.TimeUtils;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.invengo.base.utils.BeanMapperUtils;
import com.invengo.base.utils.RequestBodyUtils;
import com.invengo.library_db.GreenDaoManager;
import com.invengo.library_db.entity.module_check.BookBean;
import com.invengo.library_db.entity.module_check.BookCarBean;
import com.invengo.library_db.entity.module_check.offline.FlowBean;
import com.invengo.library_db.entity.module_check.offline.LogBean;
import com.invengo.library_db.entity.module_check.RecordBean;
import com.invengo.library_db.entity.module_check.ShelfBean;
import com.invengo.library_db.entity.module_check.StructBean;
import com.invengo.module_check.data.repsitory.business.source.BusinessSource;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import io.reactivex.Observable;
import io.reactivex.ObservableEmitter;
import io.reactivex.ObservableOnSubscribe;
import io.reactivex.ObservableSource;
import io.reactivex.ObservableTransformer;
import io.reactivex.SingleSource;
import io.reactivex.functions.BiConsumer;
import io.reactivex.functions.Consumer;
import io.reactivex.functions.Function;
import io.reactivex.functions.Predicate;
import io.reactivex.internal.operators.maybe.MaybeCallbackObserver;
import io.reactivex.schedulers.Schedulers;
import java8.util.stream.Collectors;
import java8.util.stream.StreamSupport;
import me.goldze.mvvmhabit.http.BaseBean;
import me.goldze.mvvmhabit.http.UpdateResult;
import me.goldze.mvvmhabit.http.interceptor.logging.LocalLogUtil;
import me.goldze.mvvmhabit.utils.KLog;
import me.goldze.mvvmhabit.utils.RxUtils;
import me.goldze.mvvmhabit.utils.cache.ACache;
import me.goldze.mvvmhabit.utils.cache.AKey;
import retrofit2.Call;

//本地实现
public class LocalBusinessSourceImpl implements BusinessSource {
    @Override
    public void removeByBooks(List<BookBean> bookBeans) {
        GreenDaoManager.getInstance();
    }

    @Override
    public Observable<BaseBean<BookBean>> getBookByTid(String tid) {
        System.out.println("离线TID查找图书：[ " + tid + " ]");
        return RxUtils.bindLocal(GreenDaoManager.getInstance().getBookByTid(tid), "查无此书");
    }


    @Override
    public Observable<BaseBean<BookBean>> getBookByCode(String code) {
        System.out.println("离线BARCODE查找图书：[ " + code + " ]");
        return RxUtils.bindLocal(GreenDaoManager.getInstance().getBookByCode(code), "查无此书");
    }

    @Override
    public Observable<BaseBean<ShelfBean>> getShelfInfoByCode(String shelfCode) {
        System.out.println("离线SHELFCODE查找层架：[ " + shelfCode + " ]");
        return RxUtils.bindLocal(GreenDaoManager.getInstance().getShelfInfoByCode(shelfCode), "查无此层架");
    }

    @Override
    public Observable<BaseBean<List<BookBean>>> getBookByShelfCode(String shelfCode) {
        System.out.println("离线SHELFCODE查找图书：[ " + shelfCode + " ]");
        return RxUtils.bindLocal(GreenDaoManager.getInstance().getBookByShelfCode(shelfCode), "此层架下没有书本");
    }

    @Override
    public Observable<BaseBean<List<BookBean>>> getBookByMultiShelf(String startCode, String endCode, String BookCountlimit) {
        System.out.println("离线层架区间查找图书：[ " + startCode + " ] - [ " + endCode + " ]");
        if (GreenDaoManager.getInstance().getBookCount(startCode, endCode) > Integer.parseInt(BookCountlimit)) {
            return RxUtils.bindLocal(null, "图书数量超过" + BookCountlimit + ",请重新选择区间！");
        } else {
            return RxUtils.bindLocal(GreenDaoManager.getInstance().getBookByMultiShelf(startCode, endCode), "此层架下没有书本");
        }
    }

    @Override
    public Observable<BaseBean<ShelfBean>> getShelfInfoByTid(String tid) {
        System.out.println("离线TID查找层架：[ " + tid + " ] ");
        return RxUtils.bindLocal(GreenDaoManager.getInstance().getShelfInfoByTid(tid), "查无此层架");
    }

    @Override
    public Observable<BaseBean<ShelfBean>> getNextOrUpperShelf(String shelfCode, boolean isNext) {
        System.out.println("上一层下一层：[ " + shelfCode + " ] ");
        return RxUtils.bindLocal(GreenDaoManager.getInstance().getNextOrUpperShelf(shelfCode, isNext), "查询不到更多标签");
    }
    @Override
    public Observable<BaseBean<List<BookBean>>> getBookByKeyword(String keyword, Integer pageIndex, Integer pageSize) {

        return  Observable.

                just("%" + keyword + "%")
                .subscribeOn(Schedulers.io())
                .map(new Function<String, List<BookBean>>() {
                    @Override
                    public List<BookBean> apply(String s) throws Exception {
                        return GreenDaoManager.getInstance().getBookByKeyworkd(s,pageSize);
                    }
                })
                .flatMap(new Function<List<BookBean>, ObservableSource< BaseBean<List<BookBean>>>>() {
                    @Override
                    public ObservableSource< BaseBean<List<BookBean>>> apply(List<BookBean> bookBeans) throws Exception {
                        return RxUtils.bindLocal(bookBeans,"查不到图书！");
                    }
                });
//        return RxUtils.bindLocal(GreenDaoManager.getInstance().getBookByKeyworkd(keyword, pageIndex, pageSize), "查不到图书");
    }

    @Override
    public Observable<BaseBean<List<ShelfBean>>> getShelfList(String shelfCode) {
        return RxUtils.bindLocal(GreenDaoManager.getInstance().getShelfListByShelfCode(shelfCode.substring(0, 12)), "找不到列表");
    }


    @Override
    public Observable<BaseBean<UpdateResult>> forceRevokeBook(List<BookBean> bookBeans) {

        for (BookBean bookBean : bookBeans) {
            ShelfBean bean = null;
            if (!TextUtils.isEmpty(bookBean.getPretendCallNo()))
                bean = GreenDaoManager.getInstance().getshelfbyPretendIndexNum(bookBean.getPretendCallNo());
            if (bean != null) {
                KLog.e("----------------" + bean.getShelfCode() + " " + bean.getShelfName());
                bookBean.setShelfCode(bean.getShelfCode() + "");
                bookBean.setShelfName(bean.getShelfName() + "");
                bookBean.setForceSortCase(false);
            } else {
                bookBean.setShelfCode("");
                bookBean.setShelfName("");
                bookBean.setForceSortCase(false);
            }
        }
        KLog.e("执行下一步：  " + bookBeans.size());
        HashMap<String, Object> params = new HashMap<>();
        params.put("bookInfoList", bookBeans);
        params.put("nUpdateType", 0);
        String json = RequestBodyUtils.parseJson(params, false);
        return RxUtils.bindLocal(GreenDaoManager.getInstance().cacheForceRevoke(json, bookBeans), "异常情况");
    }

    @Override
    public Observable<BaseBean<UpdateResult>> forcePositioning(List<BookBean> bookBeans, String shelfCode, String shelfName) {
        for (BookBean bean : bookBeans) {
            bean.setOldShelfCode(bean.getShelfCode());
            bean.setOldShelfName(bean.getShelfName());
            bean.setShelfCode(shelfCode);
            bean.setShelfName(shelfName);
        }
        HashMap<String, Object> params = new HashMap<>();
        params.put("bookInfoList", bookBeans);
        params.put("desbookcaseno", shelfCode);//目标架位号
        return RxUtils.bindLocal(GreenDaoManager.getInstance().cacheForcePos(RequestBodyUtils.parseJson(params, false), bookBeans), "不知道为啥要失败");
    }

    @Override
    public Observable<BaseBean<UpdateResult>> bookListing(List<BookBean> bookBeans, String shelfCode, String shelfName) {
        HashMap<String, Object> params = new HashMap<>();
        params.put("bookInfoList", bookBeans);
        params.put("operateType", 0);
        return RxUtils.bindLocal(GreenDaoManager.getInstance().cacheBookListing(RequestBodyUtils.parseJson(params, true), bookBeans), "不知道为啥要失败");
    }

    @Override
    public Observable<BaseBean<UpdateResult>> inventoryBook(List<BookBean> bookBeans, String currentShelfCode, String currentShelfName, int errorCount, int inshelfCount, int borrowCount, int notOnCount) {
        HashMap<String, Object> params = new HashMap<>();
        LogBean logBean = new LogBean();
        logBean.setBorrowCount(borrowCount);
        logBean.setInshelfCount(inshelfCount);
        logBean.setErrorCount(errorCount);
        logBean.setNotOnCount(notOnCount);
        logBean.setDateTime(TimeUtils.getNowString());
        logBean.setUserId((Integer) ACache.getInstance().getAsObject(AKey.CACHE_USER_STAFF_ID));
        logBean.setShelfCode(currentShelfCode);
        List<BookBean> beans = BeanMapperUtils.transFlowBookBean(bookBeans, currentShelfCode, currentShelfName, false);
        params.put("inventorylog", logBean);
        params.put("checkedRecds", beans);
        return RxUtils.bindLocal(GreenDaoManager.getInstance().cacheInventory(RequestBodyUtils.parseJson(params, true), beans), "不知道为啥要失败");
    }

    @Override
    public Observable<BaseBean<UpdateResult>> parallelLogs(List<BookBean> bookBeans, String currentShelfCode, String currentShelfName, int errorCount, int inshelfCount, int borrowCount, int notOnCount) {
        HashMap<String, Object> params = new HashMap<>();
        LogBean logBean = new LogBean();
        logBean.setBorrowCount(borrowCount);
        logBean.setInshelfCount(inshelfCount);
        logBean.setErrorCount(errorCount);
        logBean.setNotOnCount(notOnCount);
        logBean.setDateTime(TimeUtils.getNowString());
        logBean.setUserId((Integer) ACache.getInstance().getAsObject(AKey.CACHE_USER_STAFF_ID));
        logBean.setShelfCode(currentShelfCode);
        List<BookBean> beans = BeanMapperUtils.transFlowBookBean(bookBeans, currentShelfCode, currentShelfName, true);
        params.put("parallellog", logBean);
        params.put("checkedRecds", beans);
        return RxUtils.bindLocal(GreenDaoManager.getInstance().cacheParallel(RequestBodyUtils.parseJson(params, true), beans), "不知道为啥要失败");
    }

    @Override
    public Observable<BaseBean<UpdateResult>> downBook(List<BookBean> bookBeans) {
        for (BookBean bookBean : bookBeans) {
            bookBean.setShelfCode("");
            bookBean.setShelfName("");
        }
        HashMap<String, Object> params = new HashMap<>();
        params.put("bookinfolist", bookBeans);
        params.put("operateType", 1);
        return RxUtils.bindLocal(GreenDaoManager.getInstance().cacheDownBooks(RequestBodyUtils.parseJson(params, true), bookBeans), "123123123");
    }


    @Override
    public Observable<BaseBean<UpdateResult>> insertBookDeleteLogs(List<BookBean> bookBeans) {
        HashMap<String, Object> params = new HashMap<>();
        params.put("bookinfolist", bookBeans);
        params.put("staffid", ACache.getInstance().getAsObject(AKey.CACHE_USER_STAFF_ID));
        return RxUtils.bindLocal(GreenDaoManager.getInstance().cacheinsertBookDeleteLogs(RequestBodyUtils.parseJson(params, true), bookBeans), "此功能暂不支持离线模式");
    }

    @Override
    public Observable<BaseBean<UpdateResult>> removeOld(List<BookBean> bookBeans) {
        HashMap<String, Object> params = new HashMap<>();
        params.put("bookinfolist", bookBeans);
        params.put("staffid", (Integer) ACache.getInstance().getAsObject(AKey.CACHE_USER_STAFF_ID));
        return RxUtils.bindLocal(GreenDaoManager.getInstance().removeOld(RequestBodyUtils.parseJson(params, true), bookBeans), "此功能暂不支持离线模式");
    }


    @Override
    public Observable<BaseBean<UpdateResult>> updateFirstBook(List<ShelfBean> shelfBeans) {
        HashMap<String, Object> params = new HashMap<>();
        params.put("LayerList", new Gson().toJson(shelfBeans));
        return RxUtils.bindLocal(GreenDaoManager.getInstance().cacheFirstBook(RequestBodyUtils.parseJson(params, false), shelfBeans), "此功能暂不支持离线模式");
    }

    @Override
    public Observable<BaseBean<UpdateResult>> createupdatetask(String startcode, String endcode) {
        List<Object> list = new ArrayList<>();
        list.add(String.valueOf(ACache.getInstance().getAsObject(AKey.CACHE_USER_STAFF_ID)));
        list.add(startcode);
        list.add(endcode);
        return RxUtils.bindLocal(GreenDaoManager.getInstance().cacheupdatetask(RequestBodyUtils.parseJson(list)), "此功能暂不支持离线模式");
    }

    @Override
    public Observable<BaseBean<BookCarBean>> getBookCarInfo(String carId) {
        return RxUtils.bindLocal(GreenDaoManager.getInstance().getBookCarbyId(carId), "我找不到这个书车");
    }

    @Override
    public Observable<BaseBean<UpdateResult>> bindBook2Car(List<BookBean> beans, String carId) {
        return RxUtils.bindLocal(GreenDaoManager.getInstance().bindBook2Car(beans, carId), "更新出错");
    }

    @Override
    public Observable<BaseBean<UpdateResult>> upBook2ShelfFromCar(List<BookBean> beans, String carId) {
        return RxUtils.bindLocal(GreenDaoManager.getInstance().upBook2ShelfFromCar(beans, carId), "图书排架上架出错");
    }

    @Override
    public Observable<BaseBean<UpdateResult>> listingGuide(List<BookBean> beans) {
        Integer StaffID = (Integer) ACache.getInstance().getAsObject(AKey.CACHE_USER_STAFF_ID);
        String userName = ACache.getInstance().getAsString(AKey.CACHE_USERNAME);
        for (BookBean bean : beans) {
            bean.setUserName(userName);
            bean.setUserId(StaffID);
            bean.setOpeationDate(TimeUtils.getNowString());
        }
        HashMap<String, Object> params = new HashMap<>();
        params.put("bookrecords", beans);
        return RxUtils.bindLocal(GreenDaoManager.getInstance().cacheListGuide(RequestBodyUtils.parseJson(params, true), beans), "此功能暂不支持离线模式");
    }

    @Override
    public Observable<BaseBean<UpdateResult>> changeShelf(List<BookBean> bookBeans, String shelfCode, String shelfName) {
        HashMap<String, Object> params = new HashMap<>();
        params.put("bookinfolist", bookBeans);
        params.put("operateType", 2);
        return RxUtils.bindLocal(GreenDaoManager.getInstance().changeShelf(RequestBodyUtils.parseJson(params, true), bookBeans), "层位倒架出错");
    }

    @Override
    public Observable<BaseBean<UpdateResult>> changeShelfLog(List<BookBean> bookBeans, String shelfCode) {
        HashMap<String, Object> params = new HashMap<>();
        params.put("bookinfolist", bookBeans);
        params.put("desbookcaseno", shelfCode);
        params.put("nstaffid", ACache.getInstance().getAsObject(AKey.CACHE_USER_STAFF_ID));
        return RxUtils.bindLocal(GreenDaoManager.getInstance().changeShelfLog(RequestBodyUtils.parseJson(params, true)), "层位倒架出错");
    }

    @Override
    public Observable<BaseBean<List<ShelfBean>>> getErrorShelf(String startcode, String endcode) {
        List<ShelfBean> errorList = new ArrayList<>();
        return Observable
                .fromIterable(GreenDaoManager.getInstance().getShelfBetween(startcode, endcode))
                .subscribeOn(Schedulers.io())
                .filter(bean -> !TextUtils.isEmpty(bean.getPretendIndexNum()))
                .sorted((bean, bean2) -> {
                    int compare = bean.getPretendIndexNum().compareTo(bean2.getPretendIndexNum());
                    if (compare < 0) {
                        BookBean bookByCode2 = GreenDaoManager.getInstance().getBookByCode(bean2.getFirstBookID());
                        BookBean bookByCode1 = GreenDaoManager.getInstance().getBookByCode(bean.getFirstBookID());
                        bean2.setFirstBookName(bookByCode2.getBookName());
                        bean2.setLibCD(bookByCode2.getLocationName());
                        bean.setFirstBookName(bookByCode1.getBookName());
                        bean.setLibCD(bookByCode1.getLocationName());
                        errorList.add(bean2);
                        errorList.add(bean);
                    }
                    return compare;
                })
                .toList()
                .flatMap((Function<List<ShelfBean>, SingleSource<BaseBean<List<ShelfBean>>>>) shelfBeans -> RxUtils.bindLocal(errorList, "无错误首书").singleOrError()).toObservable();
    }

    @Override
    public Observable<BaseBean<RecordBean>> getUpdateRecordList(int finishstatus, int pageindex, int pagesize) {
        List<FlowBean> flowbeans = GreenDaoManager.getInstance().getFirstTaskBean(finishstatus, pageindex, pagesize);
        List<RecordBean.ItemsDTO> collect = StreamSupport.stream(flowbeans)
                .map(bean -> {
                    List<String> data = new Gson().fromJson(bean.getBodyJson(), new TypeToken<List<String>>() {
                    }.getType());
                    RecordBean.ItemsDTO item = new RecordBean.ItemsDTO();
                    item.setDtOperateDate(bean.getDateTime());
                    item.setMinlayer(data.get(1));
                    item.setMaxlayer(data.get(2));
                    item.setUpdatedPercent(String.valueOf(0));
                    return item;
                }).collect(java8.util.stream.Collectors.toList());
        RecordBean bean = new RecordBean();
        bean.setTotalCount(collect.size());
        bean.setItems(collect);
        return RxUtils.bindLocal(bean, "层位倒架出错");
    }

    @Override
    public List<StructBean> getStructData() {
        return GreenDaoManager.getInstance().getAllStruct();
    }
}
